<?php
/**
 *
 * Optimize class
 * special for Eleanor CMS
 * author Ruslan aka Djadka
 *
 */
class Optimize extends BaseClass
{
    private $root_cache = 'cache/templates/', $css_cache = 'css/', $css = true, //Оптимизировать цсс
        $optimize_css = true, $css_file_name = 'common.css', $css_from_tags = false, $image_to_64 = false, ##########################
        $clean_html = false, $d = true, $on = true;

    public function Cache($html, $url)
    {
        if (!$this->on) {
            return $html;
        }
        if (!$html && !$url) {
            trigger_error('Data not found');
        }
        if ($this->clean_html) {
            $html = $this->clean_file($html);
        }
        if (is_file($this->root_cache . $this->css_cache . $this->css_file_name) && !$this->d && $this->css) {
            return $this->ReplaceInHtml($html, $this->root_cache . $this->css_cache . $this->css_file_name, 1);
            //				return;
        }
        // $start = microtime();

        if ($this->css) {
            $file['source'] = $url . 'templates/AutoDiagnostika/style/common.css';
            $file['cache'] = $this->root_cache . $this->css_cache . $this->css_file_name;
            $html = $this->ReplaceInHtml($html, $file);
        }
        // $html .= '<br>TTT: '.$finish = microtime() - $start;
        return $html;
    }

    private function ReplaceInHtml($html, $file, $from_cache = null)
    {
        // $start = microtime();
        if ($from_cache) {
            //			$replace = unserialize(file_get_contents($this->root_cache . $this->css_cache .'css_inf'));
            $cs = '<link href="' . $file . '" rel="stylesheet" type="text/css">' . "\n";
        } else {
            $cs = $this->css_data($file);
            //			file_put_contents($this->root_cache . $this->css_cache .'css_inf', serialize($replace));
        }
        $html = str_replace('<link rel="stylesheet" type="text/css" href="/templates/AutoDiagnostika/style/common.css">', $cs, $html);

        // if ($css_from_tags) {
        // $html = str_replace($css_from_tags[0], '', $html);
        // $html = str_replace(array('<style type="text/css" media="all">', '</style>'), array(''), $html);
        // }
        // $html .= 'TT: '. $finish = microtime() - $start;
        return $html;
    }

    /**
     * Optimize CSS files
     *
     * @param array $data - CSS files paths
     * @param array $cs - CSS файлы из страницы между тегами style
     * @return string $css - сылку на цсс
     */
    private function css_data($data)
    {
        $combined_file = file_get_contents($data);

        // Optimize CSS Code.
        if ($this->optimize_css) {
            $combined_file = $this->OptimizeCss($combined_file);
        }
        if ($this->image_to_64) {
            $combined_file = $this->ImportFiles($combined_file);
        }

        $combined_file = $this->css_abs($combined_file, $data['source']);

        if (!is_dir($this->root_cache) && !is_dir($this->root_cache . $this->css_cache)) {
            $this->CreateFolders();
        }
        file_put_contents($data['cache'], $combined_file);

        return '<link href="' . $data['cache'] . '" rel="stylesheet" type="text/css">' . "\n";
    }

    public function CreateFolders()
    {
        if (!is_dir($this->root_cache)) {
            mkdir($this->root_cache);
        }
        if (!is_dir($this->root_cache . $this->css_cache)) {
            mkdir($this->root_cache . $this->css_cache);
        }
    }

    /*Бывают такие моменты что в коде идёт сокращения пути, так как цсс потом идёт в папку кеш
        функци которая делает полный путь
        @param string $css - весь цсс код который будет обрабатываться
        @param string $l - путь вытянутый с функции, который будет подстовляться возможно лучше сделать отдельную переменную
        @return string $css
    */
    private function css_abs($css)
    {
        global $Eleanor;
        if (strpos($css, '../') !== false) {
            if (strpos($css, '//') !== false) {
                str_replace('//', '/', $css);
            }
            $css = str_replace('../../', '/templates/', $css);
            return str_replace('../', $Eleanor::GetTemplatePath(), $css);
        } else {
            return $css;
        }
    }

    private function ServerPath($css)
    {
        global $Eleanor;
        if (strpos($css, '../') !== false) {
            if (strpos($css, '//') !== false) {
                str_replace('//', '/', $css);
            }
            $css = str_replace('../../', $Eleanor::$rootf . 'templates/', $css);
            return str_replace('../', $Eleanor::$rootf . $Eleanor::GetTemplatePath(), $css);
        } else {
            return $css;
        }
    }

    /**
     * Import files into the CSS, base64-ized.
     * @url(image.jpg) images will be loaded and their content merged into the original file, to save HTTP requests.
     *
     * @param string $source The file to import files for.
     * @param string[optional] $path The path the data should be written to.
     * @return string
     */
    public function ImportFiles($css, $path = false)
    {
        global $Eleanor;
        $css = $this->ServerPath($css);
        if (preg_match_all('/url\((["\']?)((?!["\']?data:).*?\.(gif|png|jpg|jpeg|svg|woff))\\1\)/i', $css, $matches)) {
            // dump($matches);
            $search = $replace = array();
            // $abs_path = $path;
            foreach ($matches[2] as $k => $match) {
                // $path = $abs_path . pathinfo($match, PATHINFO_BASENAME);
                Eleanor::$nolog = true;
                $img = @getimagesize($match);
                Eleanor::$nolog = false;
                // dump($img);
                if ((0 < $img[2]) && ($img[2] < 4) && (filesize($path) <= 20480)) {
                    // $image = base64_encode(file_get_contents($path));
                    $search[] = $matches[0][$k];
                    $replace[] = 'url(\'data:' . $img['mime'] . ';base64,' . base64_encode(file_get_contents($match)) . '\')';
                }
            }
            // dump($search);
            $css = str_replace($search, $replace, $css);
            return str_replace($Eleanor::$rootf, PROTOCOL . $Eleanor::$domain . $Eleanor::$site_path, $css);
        } else {
            return $css;
        }
    }

    public function headOptimize($thead, $url)
    {
        if ($this->js) {
            preg_match_all('{<script.*?src=\"(.*?\.js)\".*?></script>}i', $thead, $js);
            if ($js) {
                // if (is_file($this->root_cache . $this->css_cache . $this->js_file))
                foreach ($js[1] as $v) {
                    if (strpos($v, 'http://') === false && !is_file($url . $v)) {
                        $file['source'][] = $url . $v;
                    }
                }
                $js_link = $this->_js($file);
                return str_replace($js[0], array($js_link), $thead);
            }
        }
    }

    /** Remove white space, comments etc.*/
    private function clean_file($content)
    {
        //		$content = preg_replace('/^\s+|\n|\r|\s+$/m', null, $content);
        $content = preg_replace('!/\*[^*]*\*+([^/][^*]*\*+)*/!', '', $content);
        //		$content = str_replace(array(
        //			"\r\n","\r","\n","\t",'  ','    ','    '
        //		),'',$content);
        $content = preg_replace(
            array(
                '(( )+{)',
                '({( )+)'
            ),
            '{',
            $content
        );
        $content = preg_replace(
            array(
                '(( )+})',
                '(}( )+)',
                '(;( )*})'
            ),
            '}',
            $content
        );
        $content = preg_replace(
            array(
                '(;( )+)',
                '(( )+;)'
            ),
            ';',
            $content
        );
        $content = preg_replace(
            array(
                '(:( )+)',
                '(( )+:)'
            ),
            ':',
            $content
        );
        $content = preg_replace('/(\s|)\,(\s|)/', ',', $content);
        return $content;
    }

    private function OptimizeCss(&$css)
    {
        require_once Eleanor::$rootf . 'core/others/cssjs.optimize/cssmin.php';
        $css = CssMin::minify($css);

        //            $cssFix = new CSSfix();
        //            $cssFix->from_string($css);
        //            $css = $cssFix->generate();

        return $css;
    }
}
